\defmodule {GammaProcessPCA}

Represents a \emph{gamma} process sampled using the principal
component analysis (PCA).  To simulate the gamma process at times
$t_0 < t_1 < \cdots < t_d$ by PCA sampling, a Brownian
motion $\{ W(t), t \geq 0 \}$ with mean $0$ and variance parameter $\nu$ is
first generated at times $t_0 < t_1 < \cdots < t_d$
by PCA sampling (see class \class{BrownianMotionPCA}).
The independent increments $W(t_{j}) - W(t_{j-1})$ of this process
are then transformed into independent $U(0, 1)$ random variates $V_{j}$ via
$$ V_j = \Phi\left(\sqrt{\tau_j-\tau_{j-1}} [W(\tau_j)-W(\tau_{j-1})]\right),
\quad j=1,\dots,s $$
Finally, the increments of the Gamma process are computed as
$ Y(t_{j}) - Y(t_{j-1}) = G^{-1}(V_j)$, where $G$ is the gamma distribution
 function.

\bigskip\hrule\bigskip

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{code}
\begin{hide}
/*
 * Class:        GammaProcessPCA
 * Description:
 * Environment:  Java
 * Software:     SSJ
 * Copyright (C) 2001  Pierre L'Ecuyer and Universite de Montreal
 * Organization: DIRO, Universite de Montreal
 * @authors      Jean-Sebastien Parent and Maxime Dion
 * @since        july 2008

 * SSJ is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License (GPL) as published by the
 * Free Software Foundation, either version 3 of the License, or
 * any later version.

 * SSJ is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * A copy of the GNU General Public License is available at
   <a href="http://www.gnu.org/licenses">GPL licence site</a>.
 */
\end{hide}
package umontreal.iro.lecuyer.stochprocess;\begin{hide}
import umontreal.iro.lecuyer.rng.*;
import umontreal.iro.lecuyer.probdist.*;
import umontreal.iro.lecuyer.randvar.*;
import umontreal.iro.lecuyer.stat.*;
import umontreal.iro.lecuyer.stat.list.*;
\end{hide}

public class GammaProcessPCA extends GammaProcess \begin{hide} {
    double[] arrayTime;
    BrownianMotionPCA BMPCA;

\end{hide}
\end{code}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection* {Constructors}
\begin{code}

   public GammaProcessPCA (double s0, double mu, double nu,
                           RandomStream stream)\begin{hide} {
        super (s0, mu, nu,  new GammaGen (stream, new GammaDist (1.0)));
        this.BMPCA = new BrownianMotionPCA(0.0, 0.0, Math.sqrt(nu), stream);
    }\end{hide}
\end{code}
\begin{tabb} Constructs a new \texttt{GammaProcessPCA} with parameters
$\mu = \texttt{mu}$, $\nu = \texttt{nu}$ and initial value $S(t_{0}) = \texttt{s0}$.
The random variables are created using  \texttt{stream}.
Note that the same \externalclass{umontreal.iro.lecuyer.rng}{Random\-Stream}
 is used for the \texttt{GammaProcessPCA} and for the
\class{BrownianMotionPCA} included in this class.  Both the
\class{GammaProcessPCA} and the \class{BrownianMotionPCA} are generated by
inversion.
\end{tabb}
\begin{code}

   public GammaProcessPCA (double s0, double mu, double nu, GammaGen Ggen)\begin{hide} {
        super(s0, mu, nu, Ggen);
        this.BMPCA = new BrownianMotionPCA(0.0, 0.0, Math.sqrt(nu), Ggen.getStream());
    }\end{hide}
\end{code}
\begin{tabb} Constructs a new \texttt{GammaProcessPCA} with parameters
$\mu = \texttt{mu}$, $\nu = \texttt{nu}$ and initial value $S(t_{0}) = \texttt{s0}$.
All the random variables, i.e. the gamma ones and the normal ones,
are created using the \externalclass{umontreal.iro.lecuyer.rng}{RandomStream}
included in the \externalclass{umontreal.iro.lecuyer.randvar}{GammaGen}
\texttt{Ggen}. Note that the parameters of the
\externalclass{umontreal.iro.lecuyer.randvar}{GammaGen} object
are not important since the implementation forces the generator
to use the correct parameters (as defined above).
\end{tabb}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection* {Methods}
\begin{code}\begin{hide}

   public double[] generatePath() {
        double[] uniformsV = new double[d];
        arrayTime = BMPCA.getObservationTimes();
        int i;
        double[] BMpath = BMPCA.generatePath();
        double sigma;
        for(i = 0; i < d; i++){
            sigma = BMPCA.getSigma() * Math.sqrt(arrayTime[i + 1] - arrayTime[i]);
            uniformsV[i] = NormalDist.cdf01( ( BMpath[i+1] - BMpath[i] )/sigma);
        }
        path[0] = x0;
        for(i = 0; i < d; i++){
            path[i+1] = path[i] +
               GammaDist.inverseF(mu2dtOverNu[i], muOverNu, 10, uniformsV[i]);
        }
        observationIndex   = d;
        observationCounter = d;
        return path;
    }


   public double[] generatePath (double[] uniform01)  {
        double[] uniformsV = new double[d];
        arrayTime = BMPCA.getObservationTimes();
        int i;
        double[] BMpath = BMPCA.generatePath(uniform01);
        double sigma;
        for(i = 0; i < d; i++){
            sigma = BMPCA.getSigma() * Math.sqrt(arrayTime[i + 1] - arrayTime[i]);
            uniformsV[i] = NormalDist.cdf01( ( BMpath[i+1] - BMpath[i] )/sigma);
        }
        path[0] = x0;
        for(i = 0; i < d; i++){
            path[i+1] = path[i] +
               GammaDist.inverseF(mu2dtOverNu[i], muOverNu, 10, uniformsV[i]);
        }
        observationIndex   = d;
        observationCounter = d;
        return path;
    }\end{hide}

   public double nextObservation()\begin{hide} {
       throw new UnsupportedOperationException ("nextObservation is not implemented in GammaProcessPCA");
    }\end{hide}
\end{code}
\begin{tabb} This method is not implemented in this class since the path
cannot be generated sequentially.
\end{tabb}
\begin{code}

   public double nextObservation (double nextT) \begin{hide} {
       throw new UnsupportedOperationException ("nextObservation is not implemented in GammaProcessPCA");
    }\end{hide}
\end{code}
\begin{tabb} This method is not implemented in this class since the path
cannot be generated sequentially.
\end{tabb}
\begin{code}

   public BrownianMotionPCA getBMPCA() \begin{hide} {
        return BMPCA;
    }
\end{hide}
\end{code}
\begin{tabb} Returns the \class{BrownianMotionPCA} that is included in the
\class{GammaProcessPCA} object.
\end{tabb}
\begin{code}

   public void setObservationTimes (double[] t, int d)\begin{hide} {
        super.setObservationTimes(t, d);
        BMPCA.setObservationTimes(t, d);
    }\end{hide}
\end{code}
\begin{tabb} Sets the observation times of the \class{GammaProcessPCA} and the
\class{BrownianMotionPCA}.
\end{tabb}
\begin{code}

   public void setParams (double s0, double mu, double nu)\begin{hide} {
        super.setParams(s0, mu, nu);
        BMPCA.setParams(0.0, 0.0, Math.sqrt(nu));
    }\end{hide}
\end{code}
\begin{tabb} Sets the parameters \texttt{s0}, $\mu$ and $\nu$ to new values, and sets
the variance parameters of the \class{BrownianMotionPCA} to $\nu$.
\end{tabb}
\begin{code}

   public void setStream (RandomStream stream) \begin{hide} {
        super.setStream(stream);
        this.BMPCA.setStream(stream);
}\end{hide}
\end{code}
\begin{tabb}
Resets the \externalclass{umontreal.iro.lecuyer.rng}{RandomStream}
of the gamma generator and the
\externalclass{umontreal.iro.lecuyer.rng}{RandomStream} of
the inner \class{BrownianMotionPCA} to
\texttt{stream}.
\end{tabb}
\begin{code}\begin{hide}
}
\end{hide}
\end{code}
